#!/usr/bin/perl -w

# wysyłanie smsów przez portal playmobile.pl - sieć PLAY do wszystkich
# autor  Piotr Szydełko <wiertel@users.sourceforge.net>
# duże części wklejone z sms.orange.pl
# działa ale obecnie jest tu paskudny bałagan, obsługa błędów w powijakach

use strict;
use HTTP::Request::Common;
use HTTP::Cookies;
use LWP::UserAgent;
use Crypt::SSLeay;
# use LWP::Debug qw(+ -conns);
# LWP::Debug::trace('send()');

# ----------------------- pomocnicze -------------------------
my $debug = 0;				# czy "tryb gadatliwy"
my $mode = 0;				# czy pracujemy z raportami doręczenia
my $wait_secs = 0;			# opóźnienie oczekiwania na raport

sub debug { if ($debug) { print "[", shift, "]\n"; } }

sub zakoncz {
  my ($tekst, $ret) = @_;
  print "$tekst\n";
  exit $ret;
}

# format struktury danych:
# string który możemy znaleźć w odpowiedzi z serwera =>
# [co należy z niego wywnioskować-opis, kod powrotu ze skryptu ]
my %odpowiedzi = (
	"Skrzynka wiadomości" => ["Wszystko OK", 0],
	"Zły numer" => ["Zły numer!", 2],
	"został wyczerpany" => ["Limit wiadomości na dziś przekroczony!", 3]
);

# getCookie ($nazwa) -> wartość cookie; wymaga: $cookie_jar.
my $ckey = "";
my $cval = "";
my $cookie_jar = HTTP::Cookies->new(file => "lwpcookies.txt", autosave => 1, ignore_discard => 1);

# zwraca wartość ciasteczka dla podanej nazwy klucza
sub cookieScanner {
	# my $i; for ($i=0; $i<5; $i++) { print $i, " : ", $_[$i], "\n"; }
	($ckey eq $_[1]) and $cval = $_[2]; 
}
sub getCookie {
	$cval = "";
	$ckey = shift;
	$cookie_jar->scan (\&cookieScanner);
	return $cval;
}

my $ua = new LWP::UserAgent;
$ua->timeout(10);
$ua->agent("Mozilla/5.0 (X11; U; Linux i686; pl; rv:1.9.0.1) Gecko/2008120121 Firefox/3.0.5");
$ua->env_proxy();
$ua->cookie_jar($cookie_jar);

# odwiedza stronę $_[0]; w razie błędu wychodzi z tekstem $_[1] i kodem $_[2].
# w zmiennej globalnej $res ląduje HTML -- wynik zapytania.
my $res; my $req;
my $last_visited;
sub visit {
		my $response;
		$req = $_[0];
		if (defined $last_visited) {
			$req->referer($last_visited);
		};
        $response = $ua->request ($req);
        if (!($response->is_success)) { zakoncz($_[1], $_[2]); }
		$last_visited = $response->request->uri;

		return $response;
}

sub getFormSubmitReq {
	my $response = $_[0];
	my $fillin; my $req;
	if($#_ > 0) {
		$fillin = $_[1];
	}
	my @elems; my $elem; my $text;
	my $method; my $action; my @fields = ();
	my $name; my $value;
	$text = $response->content;
	#open(DAT, 'loguj.html');
	#$text = join(' ', <DAT>);
	#close(DAT);
	#$text =~ s/>/>\n/g;
	@elems = split(/>/, $text);
	foreach $elem (@elems) {
		$elem =~ s/^\s+|\s+$//;
		if(!$elem) {
			next;
		};
		#print(" >>  ", $elem, "\n");
		if($elem =~ /<form/i) {
			$elem =~ /method=['"](\w+)['"]/i;
			$method = $1;
			$elem =~ /action=['"]([^'"]+)['"]/i;
			$action = $1;
			if($action =~ /^\//) {
				my $prohost = $response->base;
				$prohost =~ s/\.pl\/.*/.pl/;
				$action = $prohost . $action;
			} else {
				if($action !~ /\w+:\/\//) {
					my $base = $response->base;
					$base =~ s/\/[^\/]*$/\//;
					$action = $base . $action;
				}
			}
			if($debug) {
				print "FORM\t$method\t$action\n";
			}
		};
		if($elem =~ /^<input/i) {
			$elem =~ /name=['"](\w+)/i;
			$name = $1;
			$value = '';
			if(defined($fillin->{$name})) {
				$value = $fillin->{$name};
			} else {
				if($elem =~ /value=['"]([^'"]*)['"]/i) {
					$value = $1;
				};
			};
			# buttony normalnie nie są submitowane
			if($elem !~ /type=.image./ or defined($fillin->{$name})) {
				push @fields, $name => $value;
			}
			#$fields = (@fields, $name, $value);
			#print "INPUT\t$name\t$value\n";
		};
		if($elem =~ /^<textarea/i or $elem =~ /^<select/i) {
			$elem =~ /name=['"](\w+)/i;
			$name = $1;
			if(defined($fillin->{$name})) {
				$value = $fillin->{$name};
			} else {
				$value = '';
			};
			push @fields, $name => $value;
		};
	};
	if($method =~ /post/i) {
		$req = POST $action, \@fields;
	} else {
		$req = GET $action, \@fields;
	}
	return $req;
}

# ----------------------- main() -----------------------------

select(STDERR); $| = 1;     # make unbuffered
select(STDOUT); $| = 1;     # make unbuffered

if ($#ARGV != 3 ) { zakoncz ("Zła ilość parametrów - podaj numer i treść sms-a", 6); }

my $numer = $ARGV[0];
my $tresc = $ARGV[1];
my $username = $ARGV[2];
my $password = $ARGV[3];
 
$numer =~ s/^\+48//;
$numer =~ s/^00//;

push @{ $ua->requests_redirectable }, 'POST';

# --------- konwersacja -----------

# 1. spróbuj od razu dostać się do bramki
$res = visit(GET "https://bramka.play.pl", 
       "Błąd przy dostępie do bramki [1]", 1);
if($res->content =~ /action="https:..logowanie.play.pl/) {
	# 2. przejście do strony logowania
	$req = getFormSubmitReq($res);
	$res = visit($req, 'przekierowanie do strony logowania', 1);
	if($res->content !~ /<form .* action="https:..bramka.play.pl/) {
		if($res->content !~ /<form name="loginForm"/) {
		    print "REQUEST:\n", $req->as_string, "\nRESPONSE:\n", $res->as_string, "\n";
			zakoncz("Lipa", 1);
		}
		$req = getFormSubmitReq($res, {'login' => $username, 'password' => $password});
		$res = visit($req, 'zalogowanie', 1);
		if($res->content !~ /<form .* action="https:..bramka.play.pl/) {
		    print "REQUEST:\n", $req->as_string, "\nRESPONSE:\n", $res->as_string, "\n";
			zakoncz("I nie zalogowany", 2);
		}
	};
	$req = getFormSubmitReq($res);
	$res = visit($req, 'przekierowanie do bramki sms', 1);
	if($res->content =~ /<form method="POST" action="j_security_check"/i) {
		$req = getFormSubmitReq($res);
		$res = visit($req, 'przekierowanie do bramki sms', 1);
	}
}

if($res->content =~ /<form name="smsComposeForm"/) {
	# Zalogowany! :)   ale to nie ta strona
	$req = GET 'https://bramka.play.pl/composer/public/editableSmsCompose.do';
	$res = visit($req, 'smsy', 2);
}
$req = getFormSubmitReq($res, {'czas'=>0, 'recipients'=>$numer, 'content_out'=>$tresc, 'content_in'=>$tresc, 'composedMsg'=>$tresc, 'sendform'=>'on'});
$res = visit($req, 'przeslanie tresci smsa', 3);
if($res->content =~ /SMS_SEND_CONFIRMED/) {
	# żąda potwierdzenia
	$req = getFormSubmitReq($res, {'SMS_SEND_CONFIRMED'=>'Wyślij'});
	$res = visit($req, 'potwierdzenie chęci wysłania', 3);
}
if($res->content =~ /Wiadomość została wysłana/) {
	print "OK\n";
} else {
	print "REQUEST:\n", $req->as_string, "\nRESPONSE:\n", $res->as_string, "\n";
};

